package com.wrenchmonkeys;

import java.awt.image.BufferedImage;

import javacream.resource.ImageResourceHandler;
import javacream.resource.ResourceManager;
import javacream.scene.sprite.Sprite;
import javacream.scene.sprite.SpriteResourceHandler;
import javacream.system.Platform;

import com.jme.image.Texture;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmebananas.game.console.Console;
import com.jmebananas.game.hud.SpriteButton;
import com.jmebananas.game.state.TileGameState;
import com.jmebananas.game.tile.SpriteTile;
import com.jmebananas.game.tile.Tile;
import com.jmebananas.renderer.pass.DebugRenderPass;
import com.jmebananas.util.Constants;
import com.jmebananas.util.UniqueName;
import com.jmex.game.StandardGame;

/**
 * MainGameState
 * 
 * @author Glenn Powell
 *
 */
public class MainGameState extends TileGameState {
	
	private DebugRenderPass debugPass;
	
	private SpriteButton button;
	
	private float angle = 0;

	
	public MainGameState(String name, StandardGame game) {
		super(name, game);
	}

	protected void init() throws Exception {
		super.init();
		
		Platform platform = Platform.getPlatform();
		
		setConsole(new Console(TextureManager.loadTexture(ResourceManager.getURL(Constants.DEFAULT_FONT_PATH),
				Texture.MM_LINEAR, Texture.FM_LINEAR), 0.7f, (platform.getOS() == Platform.OS.MAC ? 0 : KeyInput.KEY_GRAVE), 10, false));
		
		DisplaySystem.getDisplaySystem().getRenderer().enableStatistics(true);

		MouseInput.get().setCursorVisible(true);

		KeyBindingManager.getKeyBindingManager().set("toggle_pause", KeyInput.KEY_P);
		KeyBindingManager.getKeyBindingManager().set("screen_shot", KeyInput.KEY_F1);
		KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
		
		int displayWidth = game.getDisplay().getWidth();
		int displayHeight = game.getDisplay().getHeight();
		
		//XXX: DEBUG
		ResourceManager.addResourceHandler(BufferedImage.class, new ImageResourceHandler());
		ResourceManager.addResourceHandler(Sprite.class, new SpriteResourceHandler());

		Tile quad = new Tile("quad");
		quad.setSize(displayWidth, displayHeight);
		quad.setIsCollidable(false);
		add(quad);
		quad.getMesh().setRandomColors();

		Sprite sprite = ResourceManager.read(Sprite.class, "/oval.spr");
		sprite.setCurrentAnimation("idle");
		
		for (int i = 0; i < 6; ++i) {
			float angle = i * (FastMath.PI / 3);

			SpriteTile spriteTile = new SpriteTile(UniqueName.createName("sprite"), sprite);
			spriteTile.setLocalTranslation(displayWidth * 0.5f, displayHeight * 0.5f, 0);
			spriteTile.getLocalRotation().fromAngles(0, 0, angle);
			spriteTile.setColor((i / 5.0f), 1 - (i / 5.0f), 0.2f, 1);
			add(spriteTile);
	
			spriteTile = new SpriteTile(UniqueName.createName("sprite"), sprite);
			spriteTile.setLocalTranslation(displayWidth * 0.5f + -189 * FastMath.sin(angle), displayHeight * 0.5f + -189 * FastMath.cos(angle), 0);
			spriteTile.getLocalRotation().fromAngles(0, 0, angle + (2 * FastMath.PI / 3));
			spriteTile.setColor((i / 5.0f), 1 - (i / 5.0f), 0.2f, 1);
			add(spriteTile);
		}

		Sprite buttonSprite = ResourceManager.read(Sprite.class, "/buttons.spr");
		buttonSprite.setCurrentAnimation("idle");
		button = new SpriteButton(UniqueName.createName("button"), buttonSprite);
		button.setLocalTranslation(displayWidth * 0.4f, displayHeight * 0.2f, 0);
		add(button);

		debugPass = new DebugRenderPass(this);
		addPass(debugPass);
		
		getTileRenderPass().setRenderBounds(true);
		// //// ^^^^^
	}
	
	public void consoleExecuted(Console console, String command) {
		if (command.equalsIgnoreCase("memory")) {
			long totMem = Runtime.getRuntime().totalMemory();
			long freeMem = Runtime.getRuntime().freeMemory();
			long maxMem = Runtime.getRuntime().maxMemory();

			console.log("---- Memory Stats ----");
			console.log("Total : " + (totMem >> 10) + " kb");
			console.log("Free  : " + (freeMem >> 10) + " kb");
			console.log("Max   : " + (maxMem >> 10) + " kb");
		} else if (command.equalsIgnoreCase("debug")) {
			if (debugPass != null) {
				debugPass.setEnabled(!debugPass.isEnabled());
				
				console.log("Debug Display: " + (debugPass.isEnabled() ? "On" : "Off"));
			}
		} else if (command.equalsIgnoreCase("bounds")) {
			if (debugPass != null) {
				getTileRenderPass().setRenderBounds(!getTileRenderPass().isRenderBounds());
				
				console.log("Debug Render Bounds: " + (getTileRenderPass().isRenderBounds() ? "On" : "Off"));
			}
		}
		
		super.consoleExecuted(console, command);
	}

	public void update(float tpf) {
		if (KeyBindingManager.getKeyBindingManager().isValidCommand("toggle_pause", false)) {
			setPaused(!paused);
		}
		
		if (debugPass != null) {
			debugPass.setDebugText(String.format("FPS: %.3f - %s", Timer.getTimer().getFrameRate(),
					DisplaySystem.getDisplaySystem().getRenderer().getStatistics()));
		}
		
		super.update(tpf);
		
		if (MouseInput.get().isButtonDown(0)) {
			//int mouseX = MouseInput.get().getXAbsolute();
			//int mouseY = MouseInput.get().getYAbsolute();
			//System.out.println(mouseX + " " + mouseY);
		}
		if (!isConsoleVisible()) {
			if (KeyInput.get().isKeyDown(KeyInput.KEY_A)) {
				angle -= 0.1f;
				button.getLocalRotation().fromAngles(0, 0, angle);
			}
			if (KeyInput.get().isKeyDown(KeyInput.KEY_S)) {
				angle += 0.1f;
				button.getLocalRotation().fromAngles(0, 0, angle);
			}
		}

		if (KeyBindingManager.getKeyBindingManager().isValidCommand("screen_shot", false)) {
			DisplaySystem.getDisplaySystem().getRenderer().takeScreenShot(this.getName() + "_" + System.currentTimeMillis());
		}
		if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
			shutdown();
		}
	}

	public void render(float tpf) {
		super.render(tpf);
	}

	public void cleanup() {
		super.cleanup();
	}

}
